import { Injectable } from '@nestjs/common';

import { msg, t } from '@lingui/core/macro';
import { ALL_METADATA_NAME } from 'twenty-shared/metadata';
import { isDefined } from 'twenty-shared/utils';

import { FlatPageLayoutWidget } from 'src/engine/metadata-modules/flat-page-layout-widget/types/flat-page-layout-widget.type';
import { PageLayoutWidgetExceptionCode } from 'src/engine/metadata-modules/page-layout/exceptions/page-layout-widget.exception';
import { FailedFlatEntityValidation } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/types/failed-flat-entity-validation.type';
import { FlatEntityUpdateValidationArgs } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/types/flat-entity-update-validation-args.type';
import { FlatEntityValidationArgs } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/types/flat-entity-validation-args.type';
import { fromFlatEntityPropertiesUpdatesToPartialFlatEntity } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/utils/from-flat-entity-properties-updates-to-partial-flat-entity';

@Injectable()
export class FlatPageLayoutWidgetValidatorService {
  constructor() {}

  public validateFlatPageLayoutWidgetUpdate({
    flatEntityId,
    flatEntityUpdates,
    optimisticFlatEntityMapsAndRelatedFlatEntityMaps: {
      flatPageLayoutWidgetMaps: optimisticFlatPageLayoutWidgetMaps,
    },
  }: FlatEntityUpdateValidationArgs<
    typeof ALL_METADATA_NAME.pageLayoutWidget
  >): FailedFlatEntityValidation<FlatPageLayoutWidget> {
    const validationResult: FailedFlatEntityValidation<FlatPageLayoutWidget> = {
      type: 'update_page_layout_widget',
      errors: [],
      flatEntityMinimalInformation: {
        id: flatEntityId,
      },
    };

    const existingFlatPageLayoutWidget =
      optimisticFlatPageLayoutWidgetMaps.byId[flatEntityId];

    if (!isDefined(existingFlatPageLayoutWidget)) {
      validationResult.errors.push({
        code: PageLayoutWidgetExceptionCode.PAGE_LAYOUT_WIDGET_NOT_FOUND,
        message: t`Page layout widget to update not found`,
        userFriendlyMessage: msg`Page layout widget to update not found`,
      });

      return validationResult;
    }

    const updatedFlatPageLayoutWidget = {
      ...existingFlatPageLayoutWidget,
      ...fromFlatEntityPropertiesUpdatesToPartialFlatEntity({
        updates: flatEntityUpdates,
      }),
    };

    validationResult.flatEntityMinimalInformation = {
      id: updatedFlatPageLayoutWidget.id,
      pageLayoutTabId: updatedFlatPageLayoutWidget.pageLayoutTabId,
    };

    return validationResult;
  }

  public validateFlatPageLayoutWidgetDeletion({
    flatEntityToValidate: { id: pageLayoutWidgetIdToDelete },
    optimisticFlatEntityMapsAndRelatedFlatEntityMaps: {
      flatPageLayoutWidgetMaps: optimisticFlatPageLayoutWidgetMaps,
    },
  }: FlatEntityValidationArgs<
    typeof ALL_METADATA_NAME.pageLayoutWidget
  >): FailedFlatEntityValidation<FlatPageLayoutWidget> {
    const validationResult: FailedFlatEntityValidation<FlatPageLayoutWidget> = {
      type: 'delete_page_layout_widget',
      errors: [],
      flatEntityMinimalInformation: {
        id: pageLayoutWidgetIdToDelete,
      },
    };

    const existingFlatPageLayoutWidget =
      optimisticFlatPageLayoutWidgetMaps.byId[pageLayoutWidgetIdToDelete];

    if (!isDefined(existingFlatPageLayoutWidget)) {
      validationResult.errors.push({
        code: PageLayoutWidgetExceptionCode.PAGE_LAYOUT_WIDGET_NOT_FOUND,
        message: t`Page layout widget to delete not found`,
        userFriendlyMessage: msg`Page layout widget to delete not found`,
      });

      return validationResult;
    }

    return validationResult;
  }

  public validateFlatPageLayoutWidgetCreation({
    flatEntityToValidate: flatPageLayoutWidgetToValidate,
    optimisticFlatEntityMapsAndRelatedFlatEntityMaps: {
      flatPageLayoutWidgetMaps: optimisticFlatPageLayoutWidgetMaps,
    },
  }: FlatEntityValidationArgs<
    typeof ALL_METADATA_NAME.pageLayoutWidget
  >): FailedFlatEntityValidation<FlatPageLayoutWidget> {
    const validationResult: FailedFlatEntityValidation<FlatPageLayoutWidget> = {
      type: 'create_page_layout_widget',
      errors: [],
      flatEntityMinimalInformation: {
        id: flatPageLayoutWidgetToValidate.id,
        pageLayoutTabId: flatPageLayoutWidgetToValidate.pageLayoutTabId,
      },
    };

    const existingFlatPageLayoutWidget =
      optimisticFlatPageLayoutWidgetMaps.byId[
        flatPageLayoutWidgetToValidate.id
      ];

    if (isDefined(existingFlatPageLayoutWidget)) {
      const flatPageLayoutWidgetId = flatPageLayoutWidgetToValidate.id;

      validationResult.errors.push({
        code: PageLayoutWidgetExceptionCode.INVALID_PAGE_LAYOUT_WIDGET_DATA,
        message: t`Page layout widget with id ${flatPageLayoutWidgetId} already exists`,
        userFriendlyMessage: msg`Page layout widget already exists`,
      });
    }

    return validationResult;
  }
}
